package com.scsoft.dataacceptor.server;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Calendar;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.scsoft.dataacceptor.util.TimeUtil;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
	private static final Logger log = LoggerFactory.getLogger(NettyServerHandler.class);
	private NettyServer nettyServer;
	
	public NettyServerHandler(NettyServer nettyServer) {
		super();
		this.nettyServer = nettyServer;
	}

	public NettyServer getNettyServer() {
		return nettyServer;
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
		log.info("request:{}",msg);
		try{
			JSONObject request = JSON.parseObject(msg);
			String cmd = request.getString("cmd");
			JSONObject reqcontent = request.getJSONObject("content");
			
			JSONObject record = new JSONObject();
			Date monitortime = TimeUtil.getMonitorTime(reqcontent.getIntValue("time"));
			String mtime = TimeUtil.sdf.format(monitortime);
			record.put("SNCODE", reqcontent.getString("SN"));// 设备编号
			record.put("MONITORCODE", 102);// 监测设备类型代码
			record.put("MONITORTIME", mtime);// 监测时间
			JSONObject data = new JSONObject();
			data.put("TVOCs", reqcontent.getDouble("value"));
			record.put("MONITORDATA", data);
			record.put("DATASOURCE", "wanwei");//数据来源
			record.put("CREATETIME", TimeUtil.getCurrentTime());//创建时间
			record.put("CALCULFLAG", "0");
			record.put("CMD", cmd);
			record.put("CLIENTIPPORT", ctx.channel().remoteAddress().toString());
			record.put("SERVERIPPORT", nettyServer.getServerIpPort());
			record.put("UNITS", reqcontent.getString("units"));
			record.put("SERIALNUMBER", reqcontent.getString("serialNumber"));
			record.put("T1D", mtime.substring(0, 10));
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(monitortime);
			int min = calendar.get(Calendar.MINUTE);
			int num = min % 5;
			calendar.add(Calendar.MINUTE, 5 - num);
			calendar.set(Calendar.SECOND, 0);
			record.put("T5M", TimeUtil.sdf.format(calendar.getTime()));// 所属5分钟值

			calendar.setTime(monitortime);
			calendar.add(Calendar.HOUR_OF_DAY, 1);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MINUTE, 0);
			record.put("T1H", TimeUtil.sdf.format(calendar.getTime()));// 所属1小时值
			
			nettyServer.saveToQueue(record.toJSONString());
			
			JSONObject response = new JSONObject();
			response.put("status", "ok");
			JSONObject content = new JSONObject();
			content.put("cmd", cmd);
			content.put("SN", reqcontent.getString("SN"));
			content.put("time", reqcontent.get("time"));
			response.put("content", content);
			String repstr = response.toJSONString();
			log.info("response:{}",repstr);
			ctx.writeAndFlush(repstr);
		} catch(Exception e){
			log.warn("parse exception!",e);
		}
	}
	
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		cause.printStackTrace();
		log.warn("会话异常", cause);
		ctx.close();
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		SocketAddress address = ctx.channel().remoteAddress();
		log.info("SocketAddress.toString()=ctx.channel().remoteAddress().toString():{}",address.toString());
		InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
		if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
			log.info("HostName:{},HostString:{},Port:{},HostAddress:{}",insocket.getHostName(),insocket.getHostString(),insocket.getPort(),insocket.getAddress().getHostAddress());
			log.info(insocket.getAddress().getClass().getName());
			IdleStateEvent event = (IdleStateEvent) evt;
			if (event.state() == IdleState.READER_IDLE)
				log.info("{} read idle",insocket.getPort());
			else if (event.state() == IdleState.WRITER_IDLE)
				log.info("{} write idle",insocket.getAddress().getHostAddress());
			else if (event.state() == IdleState.ALL_IDLE)
				log.info("{} all idle",insocket.getAddress().getHostAddress());
		} else {
			super.userEventTriggered(ctx, evt);
		}
	}
}